pkosiec/mongo-seeding

TS Compilation errors when using Mongo Seeding along MongoDB driver v4

aleneum opened this issue ยท 11 comments

I am using mongo-seeding and mongoose in the same (typescript) project. I recently upgraded mongoose to version 6.0.4. This version of mongoose depends on mongodb 4.1.1 which does not play nicely with mongo-seeding right now.

node_modules/mongo-seeding/dist/config.d.ts:3:10 - error TS2305: Module '"mongodb"' has no exported member 'CollectionInsertManyOptions'.

3 import { CollectionInsertManyOptions, MongoClientOptions } from 'mongodb';
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~

node_modules/mongo-seeding/dist/database/database.d.ts:1:14 - error TS2305: Module '"mongodb"' has no exported member 'CollectionInsertManyOptions'.

1 import { Db, CollectionInsertManyOptions, MongoClient } from 'mongodb';
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~

node_modules/mongo-seeding/dist/database/database.d.ts:32:167 - error TS2694: Namespace 'node_modules/mongodb/mongodb"' has no exported member 'InsertWriteOpResult'.

32     insertDocumentsIntoCollection(documentsToInsert: any[], collectionName: string, collectionInsertOptions?: CollectionInsertManyOptions): Promise<import("mongodb").InsertWriteOpResult<any>>;

                         ~~~~~~~~~~~~~~~~~~~

node_modules/mongo-seeding/dist/database/database.d.ts:55:93 - error TS2694: Namespace '"node_modules/mongodb/mongodb"' has no exported member 'DeleteWriteOpResultObject'.

55     removeAllDocumentsIfCollectionExists(collectionName: string): Promise<import("mongodb").DeleteWriteOpResultObject | undefined>;
                                                                                               ~~~~~~~~~~~~~~~~~~~~~~~~~

Do you plan to upgrade mongodb (type) dependencies in the foreseeable future?

Hi @aleneum,
Thank you for your contribution.

Yes, I would like to upgrade MongoDB Node.js driver to 4.x. However, as you also noticed in #183, it would result in a breaking change in the Mongo Seeding API. That's something I would like to prevent for now, as I wouldn't like to support multiple versions of the library, or doing breaking changes too often. The current API is definitely not ideal and I would like to rethink it before doing such breaking change. So, until the MongoDB 3.x driver is supported, I would like to stick with it. The other thing is that looks like the DB connector doesn't work properly with new driver, I would need to resolve that issue - but that something minor.

That doesn't mean I don't want to support you with resolving your issue. The question is - can it be workarounded somehow?
For example, by overriding the types. - but that shouldn't be necessary. Even if Mongoose uses MongoDB 4.x, and Mongo Seeding 3.x, there shouldn't be a problem to use both clients in the same time ๐Ÿค” NPM should resolve that properly, as they are dependencies of your dependencies.

Could you please provide some minimal example how to reproduce your issue? I can play a bit with it and maybe we'll figure out some satisfying solution for both of us ๐Ÿ™‚ Cheers!

Hello @pkosiec,

However, as you also noticed in #183, it would result in a breaking change in the Mongo Seeding API.

I just use the defaults, so I cannot really tell whether getting rid of e.g. CollectionInsertManyOptions is tough or not. If you want to keep the API unchanged, you could still allow this option but emit a warning that it does not do anything anymore. But again, I don't know whether this is actually feasible or what kind of optimization could be done with it.

Even if Mongoose uses MongoDB 4.x, and Mongo Seeding 3.x, there shouldn't be a problem to use both clients in the same time ๐Ÿค” NPM should resolve that properly, as they are dependencies of your dependencies.

I guess this might be more a problem of how typescript resolves/imports dependencies than how npm or yarn does it. I created a minimal example at https://github.com/aleneum/mongo-seeding-182 for you to clone and tinker around.

Based on #183, I created a mongo-seeding and mongo-seeding-cli release that I use for now in my project.

Hi @aleneum, sorry for a long delay. I'm back from vacation and I took a look at your example.

I think I know what's wrong. In mongo-seeding I have a dependency to mongodb@3, which is fine, but the TS types @types/mongodb are missing from the production build. It results in such error.

There's also another issue inside your project. You do:

import { ObjectId } from "mongodb";

But you don't have mongodb in your package.json file.

I was able to build the app after running:

npm i mongodb --save # Install missing dependency
cd './node_modules/mongo-seeding/' && npm i @types/mongodb@3 --save --force # fix mongo DB types dependencies

I will fix the issue and publish new Mongo Seeding release soon. Thank you for helping discovering this issue!

BTW In the meantime you can also use MongoDB v3 in your app, which also makes your app build:

npm i mongodb@3
npm i @types/mongodb@3 --save-dev

Cheers!

But you don't have mongodb in your package.json file.

Hmm.. since mongodb is obviously a dependency of mongoose I though I can skip that part. But I get that this is a) not a good practice and b) can cause issues if there is a version conflict somewhere in the dependencies.

Thank you for having a look at it. Your feedback is much appreciated!

Exactly. Dependencies of your dependency can change - that's why your actual dependency list (which you import in your app) should be fully included in package.json. If mongoose changes the MongoDB driver to totally different library, once you update mongoose, your app would stop functioning.

NPM is pretty smart in resolving dependencies, avoiding duplicate downloads of the same package in the same version. So don't worry about that, and include full list of things you import in package.json ๐Ÿ™‚

BTW I will release new Mongo Seeding alpha version today and will double-check if your example builds well with it. Will let you know about that here ๐Ÿ™‚

Hi @pkosiec, did you release the mentioned Alpha with the fixed dependency entries?

Hello @aleneum and @qqilihq, I'm really sorry for a really long delay.

I've just published Mongo Seeding 3.7.1, you can try it out! ๐Ÿ™‚

When it comes to the original issue @aleneum's problem, the compilation errors still exist. However, after extra research, I learned that there is an additional solution: setting compilerOptions.skipLibCheck to true in the tsconfig.json. I believe there's no better way to handle this.

I hope that new year I will be able to publish Mongo Seeding v4 with updated MongoDB v4 driver that would resolve the inconvienence, but it's caused by the TypeScript types resolution.

@pkosiec Thanks a bunch for this! I have just updated our project, and at least for me the compile errors are gone! (I'm quite sure they were identical to what @aleneum described, as this brought me here via googling). To clarify, without having to enable the skipLibCheck (which I'd like to avoid).

Thanks for the fix -- and looking forward to the next release!

@qqilihq I'm glad to hear that! ๐Ÿ™‚

Just out of curiosity: do you also use the new MongoDB Node.js driver v4 (which has brand-new built-in TS types) as dependency in your app, similarly as @aleneum? I guess not, and that would explain that you didn't need to touch the tsconfig.json file ๐Ÿค”

@pkosiec D'oh, sorry, you're right.

(1) Yes, we have the recent "mongodb": "4.2.1" as a dependency.
(2) But I just noticed that we still had "@types/mongodb": "4.0.7"
(3) After dropping the @types/mongodb, as expected, I'll end up with:

node_modules/mongo-seeding/dist/config.d.ts:3:10 - error TS2305: Module '"mongodb"' has no exported member 'CollectionInsertManyOptions'.

3 import { CollectionInsertManyOptions, MongoClientOptions } from 'mongodb';
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~

node_modules/mongo-seeding/dist/database/database.d.ts:1:14 - error TS2305: Module '"mongodb"' has no exported member 'CollectionInsertManyOptions'.

1 import { Db, CollectionInsertManyOptions, MongoClient } from 'mongodb';
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~

node_modules/mongo-seeding/dist/database/database.d.ts:32:167 - error TS2694: Namespace '"/Users/pk/Repositories/pagefate/api/node_modules/mongodb/mongodb"' has no exported member 'InsertWriteOpResult'.

32     insertDocumentsIntoCollection(documentsToInsert: any[], collectionName: string, collectionInsertOptions?: CollectionInsertManyOptions): Promise<import("mongodb").InsertWriteOpResult<any>>;
                                                                                                                                                                         ~~~~~~~~~~~~~~~~~~~

node_modules/mongo-seeding/dist/database/database.d.ts:55:93 - error TS2694: Namespace '"/Users/pk/Repositories/pagefate/api/node_modules/mongodb/mongodb"' has no exported member 'DeleteWriteOpResultObject'.

55     removeAllDocumentsIfCollectionExists(collectionName: string): Promise<import("mongodb").DeleteWriteOpResultObject | undefined>;
                                                                                               ~~~~~~~~~~~~~~~~~~~~~~~~~


Found 4 errors.

Guess, I'll just keep the @types for now :-)

@qqilihq Thank you for clarification. I'm not sure if that will work long-term, as the @types/mongodb are for MongoDB 3, and you use v4 and there could be some differences. Anyway, if you encounter some issues with this setup, please keep in mind that there are some workarounds ๐Ÿ™‚ Cheers!