Typeorm: Migration should either read .ts or deliver a .js

Created on 28 Feb 2018  路  43Comments  路  Source: typeorm/typeorm

This is either a bug or a new feature

[ ] question
[ x] bug report
[x ] feature request
[ ] documentation issue

Database system/driver:

[ ] cordova
[ ] mongodb
[ ] mssql
[ ] mysql / mariadb
[ ] oracle
[ x] postgres
[ ] sqlite
[ ] sqljs
[ ] websql

TypeORM version:

[x ] latest
[ ] @next
[ ] 0.x.x (or put your version here)

Steps to reproduce or a small repository showing the problem:
typeorm migrations:generate -n test this create typecript file test.ts
typeorm migrations:run this fails with Unexpected token import

What solves the issue
Either call typeorm using ts-node, as explained here : https://github.com/typeorm/typeorm/issues/1561
Either transpile .ts file .js using typescript

Expected behaviour
Typeorm should be able to read the file it generated, which means : reading ts file or providing .js file

invalid

Most helpful comment

I'm with @eyelidlessness ,

a CLI that must be run SOMETIMES in a different way is just bizarre, and have it completely undocumented?

Look at it from my point of view, I'm 15 minutes into typeORM for the first time and already searching the github issues, its not a friendly welcoming.

The only solution I can think of is just

       "scripts": {                                                                                              
          "start": "ts-node src/index.ts",                                                                       
          "typeorm": "ts-node ./node_modules/.bin/typeorm"                                                       
       }

And instruct users to run with double dashes

npm run typeorm -- query "select * from user"

All 43 comments

any application you write in typescript you need to compile and run. So its quite normal that you need to compile before you run a typescript code.

The issue as reported is that TypeORM is generating files that it then cannot read. I have seen this behavior as well.

what does it mean it cannot read ?! TypeORM does not read files, node does. TypeORM generates you a file, you compile it, then your node runs js files.

What I mean is:

  1. migrations:generate generates migrations, in the form of files
  2. It is expected that migrations:run runs those migrations, by reading those files and running them - but it does not do that

If the expectation is that migrations:run accepts only JS files, then migrations:generate should generate only JS files. It is very confusing for the automatic migration generator to generate migrations that cannot be run.

wrong logic. If node can run only js files it does not mean that we need to write js files. are you new in typescript?

It's worth noting that nothing in the documentation about migrations indicates that TS migration files (whether written manually or generated by migrations:generate) need to be compiled to be run. The assumption based on the documentation is that migrations:run handles TS migrations.

It's not "wrong logic" to expect that automatically generated migrations can be run by the migrations runner. I'm not "new in typescript" and I know how transpilation works. I don't appreciate being attacked. Is this how you always address feedback?

You can take a look any of 1000+ issues and you'll find how I usually address issues.

Asking if you are "new in typescript or not" is not an "attack", it is a question. Question based on your questions, they don't make any sense to me if they are being asked by somebody who knows how typescript works.

Let me give you another question, what do you think entity:generate should generate you? js or ts file?

  1. I explained why I have the expectation that generated migrations are runnable. It is already clear I know how Typescript works.
  2. Questioning someone's experience with Typescript is addressing the person rather than what you suspect is missing knowledge. That is an attack.
  3. Even if it wasn't intended as such, when someone expresses that they feel attacked by that approach, consider understanding why the person felt that way.
  4. I have no idea what entity:generate should do, it isn't something I've looked deeply into because I would never use it. Given #1679, it isn't clear to me how it would matter, as neither TS nor JS entity files appear to work at all.

consider understanding why the person felt that way

do you really think Im going to ask you here why you felt that way? Seriously this place is not for feeling discussion. I know you felt that way simply because you did not like that I told you that you don't understand something. I still think the same. But there is nothing wrong with it - if you don't understand yet how node + typescript works together and how runtime is organized there is nothing wrong with it, you'll learn. You should not treat it as an attack. Thats a problem if you treat such things as attacks.

Do you want to know what I feel? I feel I spend 30 minutes for free trying to answer your question without harming your feelings. My wife is near me and waiting for me when I finish typing answer to you before going to sleep. Do you understand how much resources it took to answer to a simple question? And thats what I do every day.

I'll close this issue, since its not a real issue but more like a question. Consider asking questions to the community in gitter. And once you and community come with some idea or feature how to improve this come back and report a new issue.

I'm with @eyelidlessness ,

a CLI that must be run SOMETIMES in a different way is just bizarre, and have it completely undocumented?

Look at it from my point of view, I'm 15 minutes into typeORM for the first time and already searching the github issues, its not a friendly welcoming.

The only solution I can think of is just

       "scripts": {                                                                                              
          "start": "ts-node src/index.ts",                                                                       
          "typeorm": "ts-node ./node_modules/.bin/typeorm"                                                       
       }

And instruct users to run with double dashes

npm run typeorm -- query "select * from user"

a CLI that must be run SOMETIMES in a different way is just bizarre

you got it wrong, it does not have SOMETIMES in a different way. Simply, if you are using ts-node you must run ts files, if you are using node you must run js files

its not a friendly welcoming.

Im really sorry about your feelings but sometimes people forget what is open source and don't think before talking something

I'm really sorry about your feelings but sometimes people forget what is open source and don't think before talking something

Feelings has nothing to do with it, we're trying to be helpful and suggest an improvement.

The user of this CLI has no idea what's going on, it may be a bash script that sometimes runs ts-node and sometimes doesn't.

Just look at the help, nobody would think you have to sometimes run the CLI through a preprocessor after seeing this output. The actual behavior is not faithful to the implied behavior. I think if the command typeorm was replaced with something like a bash script that checked for ts-node and used it, it would be more user friendly.

(xenial)kevin@localhost:~$ typeorm --help
Usage: typeorm <command> [options]

Commands:
  typeorm schema:sync         Synchronizes your entities with database schema.
                              It runs schema update queries on all connections
                              you have. To run update queries on a concrete
                              connection use -c option.
  typeorm schema:log          Shows sql to be executed by schema:sync command.
                              It shows sql log only for your default connection.
                              To run update queries on a concrete connection use
                              -c option.
  typeorm schema:drop         Drops all tables in the database on your default
                              connection. To drop table of a concrete
                              connection's database use -c option.
  typeorm query               Executes given SQL query on a default connection.
                              Specify connection name to run query on a specific
                              connection.
  typeorm entity:create       Generates a new entity.
  typeorm subscriber:create   Generates a new subscriber.
  typeorm migration:create    Creates a new migration file.
  typeorm migration:generate  Generates a new migration file with sql needs to
                              be executed to update schema.
  typeorm migration:run       Runs all pending migrations.
  typeorm migration:revert    Reverts last executed migration.
  typeorm version             Prints TypeORM version this project uses.
  typeorm cache:clear         Clears all data stored in query runner cache.
  typeorm init                Generates initial TypeORM project structure. If
                              name specified then creates files inside directory
                              called as name. If its not specified then creates
                              files inside current directory.

Options:
  -h, --help     Show help                                             [boolean]
  -v, --version  Show version number                                   [boolean]

ts-node is a third-party tool, and have nothing to do with typeorm. You can use it, and can not to use it. typeorm executes in node, and node requires javascript files, it means if you want to execute something using CLI you need to use js files. Can you please tell me what exact problem you have and I'll try to explain more.

The issue is that certain commands operate on typescript files and others don鈥檛 but the documentation doesn鈥檛 distinguish that. It鈥檚 really that simple. It would be nice if a TS library didn鈥檛 require a user to account for that distinction but a documentation change could at least mitigate it

if you want to execute something using CLI you need to use js files

This is not always true, even in the current topic. This is the nature of the problem

ts-node is a third-party tool, and have nothing to do with typeorm.

$ typeorm init

$ grep -r ts-node .
./package.json:      "ts-node": "3.3.0",
./package.json:      "start": "ts-node src/index.ts"

$ typeorm init

it just setups you some tools that can help you during development, just like if you specify express option and will add express as well or if you specify a docker option it create you a docker-compose file. typeorm still is separate and have nothing to do with them.

Lets start from the beginning. What is exact issue and how we are suppose to fix it? As I see @eyelidlessness suggests to add notes to the documentation, if yes, then please provide a proposals on what should be added. If there can be better solution other then changing documentation, then please propose them as well and lets discuss pros and cons.

I think it comes down to - we see a very polished library, which is rare in js/ts, and find a very clunky feature to it and want to make it better. I understand what @pleerock is saying, and I understand why @eyelidlessness opened this issue, especially since I ran into this problem about 10 minutes into trying this library.

ts-node is not a "dependency" for typeorm, I absolutely agree with you, but I think it is a dependency for typeorm the CLI. This weird half dependency is probably because the cli is packaged up with library.

I'll throw this idea out there, just a suggestion. Its pretty common to have a lib and its cli separate. Like vue-cli, express-generator, etc. What about breaking out into a typeorm-cli? And not only that, but the script ./bin/typeorm-cli will depend on ts-node, and run all its commands through ts-node. It could even be bash script.

I want to add a note that ts-node is not a silver bullet here. There's currently a bug in the TypeScript compiler API that causes single-file compilation (which ts-node engages in) to fail to include decorator metadata for non-primitive globals (e.g. Date). This can cause problems with basic model definitions that otherwise work in a full project compilation.

@eyelidlessness
Does this bug equally effect my solution of ts-node always running automatically and the currently recommended way of running like

ts-node ./node_modules/.bin/typeorm migrate

Are you suggesting that typeorm CLI always generate js files? (which probably wont look that different from ts files anyway)

Does this bug equally effect my solution of ts-node always running automatically and the currently recommended way of running like

I haven't tested but I believe it would from my experience. I've worked around this in another situation by directly altering the source going into the TypeScript compiler by importing Date from another module that exports it. I'm not sure that'd be acceptable for a general solution but it worked in my project.

Are you suggesting that typeorm CLI always generate js files? (which probably wont look that different from ts files anyway)

IMO that is probably the least worst solution currently.

It would have to be very vanilla node js - no decorators, no imports, I'm not sure it would be a good fit for typeorm.

I'm not sure decorators is an issue for migrations.

No, but for others, like entity:create

Hmm, entity:create just spits out anything it wants, probably from a template, are there any commands that cause typeorm CLI to read a file and that file has to look typescripy?

What about breaking out into a typeorm-cli?

I don't want doing that. At least not now. But maybe in the future it will be.

I want to add a note that ts-node is not a silver bullet here.

that's right. I faced some very bad unresolvable issues with ts-node on windows platform that I don't have on my mac. This tool may become useful for somebody and for somebody it may be better not to use it. Its my opinion and its based on my experience working with ts-node.

Hello there.

At least we should consider updating the documentation. On the main page we stille have :

{
   "type": "mysql",
   "host": "localhost",
   "port": 3306,
   "username": "test",
   "password": "test",
   "database": "test",
   "synchronize": true,
   "logging": false,
   "entities": [
      "src/entity/**/*.ts"
   ],
   "migrations": [
      "src/migration/**/*.ts"
   ],
   "subscribers": [
      "src/subscriber/**/*.ts"
   ]
}

But we know that generating migrations using ts files won't work (as referred here => https://github.com/typeorm/typeorm/issues/1561)

I'm having terrible problems with migrations that do not read Typescript file. =/

Also had issues with this. Having the cli typeorm migration:create generate a .ts file but not be able to run it with typeorm migration:run is really confusing. A comment about this in the documentation would definitely have helped. I'm following @kswope suggestion by setting up a script in my package.json file with "typeorm": "ts-node ./node_modules/.bin/typeorm". Then since I'm using yarn I can just do yarn typeorm migration:run.

Hey I just ran into this -- a reasonable solution (in my mind) was to just change migrations config to point to the output dir that TS uses. After reading the content in this thread though I took a look at using ts-node instead.

As others have noted, another decent workaround is to install ts-node and use it to invoke typeorm, in my case I use yarn so I installed it as one of the devDependencies (along with typeorm and typescript -- not a huge fan of global installs). Then I can locally alias typeorm through packages.json's scripts section, or in a Makefile or whatever:

packages.json

"scripts": {
  "typeorm": "./node_modules/.bin/ts-node ./node_modules/.bin/typeorm"
}

Makefile

.PHONY: migrate-db

TYPEORM=./node_modules/.bin/ts-node ./node_modules/.bin/typeorm
# TYPEORM=yarn typeorm

migrate-db:
  $(TYPEORM) migration:run

Hopefully someone else finds this useful.

Maybe for now the fix is to just update the documentation to include this workaround? I can jump on it, given there's some indication that's what people actually want

hey, @t3hmrman, great suggestions 馃憤

i'm currently facing the same issue and realized that the first option won't work if you reuse the ormconfig file elsewhere in addition to CLI usage (e.g. importing it in the source and passing it to create a connection); the paths would be wrong in one of the cases.

the second one (using ts-node) seem to be the most acceptable solution, as you can have the same paths for migrations, entities etc. both for CLI and API invocations.

馃嵒

hey @eliranmal yeah you're right -- this happened to me and I actually went back to pointing at dist/path/to/migrations instead :(. An excerpt from my ormconfig.js:

   "entities": [
      "dist/src/models/**/*.js"
   ],
   "migrations": [
      "dist/src/migrations/**/*.js"
   ]

Totally forgot I made this comment otherwise I would have updated it

Ah.. this makes sense.. Thnx for your commitment, everyone..

I got it working doing the following:

Package.json:
{ "scripts": { "typeorm": "ts-node ./node_modules/.bin/typeorm" } }

npm run typeorm migration:generate -n test - FAILS due to npm not capturing the -n argument

yarn typeorm migration:generate -n test - WORKS

Also, @pleerock, you need to find some balance in life and start being not an asshole. Several people have addressed you on your behavior. This means you are affecting them. Instead of attacking them as well, maybe it's time to buy a mirror and take a good look into it.

@Matzu89, that's the same solution i ended up with.

on a different note; i think you should appreciate @pleerock's commitment just as well, if not more than everyone else's.

@Matzu89, I think you(and not only you) expect a little of enterprise support from open source library. Library is build on someone free time and most likely people answering questions will be after work so they might be more tired and jumpy. Because of that there will be no phrases like 'Dear Sir' and more strict questions, which sometimes might sound offensive(if you don't remember about the context).

As for the npm solution I think it might be failing because lack of --.
Sending command line arguments to npm script

I agree that the current behavior is quite confusing. TypeORM is clearly geared towards TypeScript and expecting that the CLI tools handles TypeScript files seamlessly seems very natural.

Currently, the CLI can't handle the very files it itself generates with typeorm init. Consider the following:

typeorm init --database mysql
npm i
typeorm schema:sync

The result of the above is that TypeORM crashes with a syntax error.

I am using .ts file and below workaround works for me.

"script": {
"typeorm": "ts-node ./node_modules/.bin/typeorm"
}

npm run typeorm migration:run

Thanks everyone :)

Guys, I agree that current behavior is confusing, but still, please consider the next points:

  • It's opensource and if you want to contribute, provide a PR, make a donate, make a RFC issue etc
  • @pleerock is not a native English speaker, so you can get him wrong

You can always create your own library as a fork of current and try to address feedback, I believe everybody understands that, so just be grateful and polite to all the contributors who spent their free time on a lib that helps you with doing your job.

@pleerock could you please lock this conversation?

Created a PR on CLI doc to explain this.
https://github.com/typeorm/typeorm/pull/3305

@havenchyk yeah lets lock it, thanks to @hkjeffchan and @wederer we added some docs to help users who face this issue.

I admit some of my answers here aren't completely appropriate. Sometimes I can get really tired answering questions. Sorry about it.

But anyway my point is still same - current issue isn't about typeorm, its about deeper understanding of typescript, javascript and how runtime actually works.

Was this page helpful?
0 / 5 - 0 ratings