Typegoose: Output ES Modules

Created on 12 Apr 2020  路  10Comments  路  Source: typegoose/typegoose

I'm targeting esnext in tsconfig, and trying to import { prop } from '@typegoose/typegoose'; fails with

SyntaxError: The requested module '@typegoose/typegoose' does not provide an export named 'prop'

Same issue that graphql-tools had.

enhancement help wanted

All 10 comments

sorry, but when doing that, it might affect older versions of node and might affect the code of the users

sorry, but when doing that, it might affect older versions of node and might affect the code of the users

I doubt it. Much bigger projects, with many more users, like graphql-tools which I linked above, have done it.

Also, graphql-modules agreed to implement ES Modules.

Anyway, there's an easy way to prevent any incompatibilities: release a new major version announcing the addition of ES Modules. That way, npm won't automatically update the user's typegoose package beyond the current version.

i have looked more into it, i would like to emit ES-Modules, but they are only included in node 13 (without flag) and from what i know are still somewhat experimental and the next version 7.0 will remove nodejs 8 support (node 10 will be the lowest supported then), so for the near future this will probably not be happening - sorry

PS: i will look into this again when the time comes

Maybe the release of Node 14 is a good reason to look into this again. I ended up using a nasty workaround to get typegoose to play with "modules": "esnext", which apparently breaks TypeScript reflection and autocompletion.

import * as typegoose from '@typegoose/typegoose';
import { DocumentType, Ref } from '@typegoose/typegoose';  // these are types
const { index, prop, arrayProp, getModelForClass, defaultClasses } = typegoose['default'] || typegoose;

One of the nice features available only with ES Modules is top-level await.

This actually brings up a bigger question; since Typegoose is targeted solely towards TypeScript users, why not remove the build step entirely and export the raw .ts files to NPM? The user then gets to decide whether to use CommonJS or ES Modules for the final output.

@101arrowz you cant really import and compile ts files installed from an provider (like npm), at least i dont know and simple way

This may work for other reasons (Gatsby uses TypeScript) but here's an example of an NPM package that only ships .ts files: https://github.com/epilande/gatsby-theme-auth0/blob/master/package.json

I think simply adding a bunch of .mjs files to the npm repository can't hurt anything. Also see: https://nodejs.org/api/esm.html#esm_conditional_exports

Everything should stay backwards compatible even if modules were supported.
https://nodejs.org/api/esm.html#esm_approach_1_use_an_es_module_wrapper

i tried to add esm and test it, but i couldnt get it to work, while also including cjs
branch: https://github.com/typegoose/typegoose/tree/feature/esm

run npm run build and it will output /lib as cjs and /lib/esm as mjs

i loaded it into my demo project
with
tsconfig

{
  "compilerOptions": {
        "target": "es6",
        "module": "ES6",
        "allowSyntheticDefaultImports": true
  }
}

and package

{
  "type": "module"
}

and code

// NodeJS: 14.7.0
// MongoDB: 4.2-bionic (Docker)
import { modelOptions, prop, getModelForClass } from "@typegoose/typegoose/lib/esm";
import mongoose from "mongoose"; // [email protected] @types/[email protected]

@modelOptions({ schemaOptions: { timestamps: true, strict: "throw", collection: "user" } })
class User {
  @prop({ required: true, index: true })
  public userId!: number;
}
const UserModel = getModelForClass(User);

(async () => {
  await mongoose.connect(`mongodb://localhost:27017/`, { useNewUrlParser: true, dbName: "esm", useCreateIndex: true, useUnifiedTopology: true });



  await mongoose.disconnect();
})();

(typegoose-testing/esm)

and got error Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/hasezoey/Downloads/typegoose-testing/node_modules/@typegoose/typegoose/lib/esm/logSettings' imported from /home/hasezoey/Downloads/typegoose-testing/node_modules/@typegoose/typegoose/lib/esm/typegoose.js
then tried to replace

import { logger } from './logSettings';
// with
import { logger } from 'logSettings';

and the next module came up - but i cant ship it this was and i didnt find an typescript option to export it the correct way

if someone can fix this and make an pr, i would merge it

I've just published a dual package using conditional exports. It can be imported by name from ESM TypeScript code ("module": "esnext").

https://github.com/dandv/local-iso-dt.

Here is the diff.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Negan1911 picture Negan1911  路  10Comments

kerolloz picture kerolloz  路  6Comments

rubenvereecken picture rubenvereecken  路  5Comments

kerolloz picture kerolloz  路  6Comments

huming2207 picture huming2207  路  8Comments