sequelize / website

Our beloved website that contains all versions of our documentations and the API references.
https://sequelize.org
29 stars 152 forks source link

Cannot import decorators-legacy in V7 #552

Open w0rldart opened 1 year ago

w0rldart commented 1 year ago

Issue Creation Checklist

Bug Description

The documentation explicitly indicates to use decorators to define all aspects related to a model. From types, to relationships, and more.

However, I personally cannot get it to work, due to this issue in my VSCode editor

Cannot find module '@sequelize/core/decorators-legacy' or its corresponding type declarations.ts(2307)

Reproducible Example

import { Model, DataTypes, InferAttributes, InferCreationAttributes, CreationOptional } from '@sequelize/core'
import { RequestType } from '../types'
import { sequelize } from '../db'

class Request extends Model<InferAttributes<Request>, InferCreationAttributes<Request>> {
  declare id: CreationOptional<number>
  declare requestType: string
  declare requestData: object
  declare requester: string
  declare createdAt: CreationOptional<Date>
  declare updatedAt: CreationOptional<Date>
}

Request.init({
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  requestType: {
    type: DataTypes.ENUM(
      RequestType.EXPENV_AZURE,
      RequestType.EXPENV_GCP,
      RequestType.VM_AZURE,
      RequestType.VM_GCP,
      RequestType.RPA_AZURE,
      RequestType.RPA_GCP,
      RequestType.AZURE_RG
    ),
    allowNull: true
  },
  requestData: {
    type: DataTypes.JSON,
    allowNull: false
  },
  requester: {
    type: DataTypes.STRING,
    allowNull: false
  },
  createdAt: {
    type: DataTypes.DATE
  },
  updatedAt: {
    type: DataTypes.DATE
  }
}, { sequelize })

However, and as per a standard example on this page, the usual flow to use decorators

import { Model, DataTypes, InferAttributes, InferCreationAttributes, CreationOptional, NonAttribute } from '@sequelize/core'
import { PrimaryKey, Attribute, AutoIncrement, NotNull, HasMany, BelongsTo } from '@sequelize/core/decorators-legacy'

has the second line, no matter what else I have in my file, always throw this error: Cannot find module '@sequelize/core/decorators-legacy' or its corresponding type declarations.ts(2307)

What do you expect to happen?

Find the module and not throw that error

What is actually happening?

Environment

$ npm list @sequelize/core
db-operator@1.0.0 
└── @sequelize/core@7.0.0-alpha.27
$ node -v
v18.12.1
npm list typescript
db-operator@1.0.0
├─┬ ts-jest@29.1.1
│ └── typescript@5.1.6
└─┬ ts-standard@12.0.2
  ├─┬ @typescript-eslint/eslint-plugin@5.62.0
  │ └─┬ tsutils@3.21.0
  │   └── typescript@5.1.6 deduped
  ├─┬ eslint-config-standard-with-typescript@23.0.0
  │ └── typescript@5.1.6 deduped
  └── typescript@5.1.6 deduped
{
  "compilerOptions": {
    "allowJs": false,
    "declaration": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "outDir": "dist",
    "rootDir": ".",
    "skipLibCheck": true,
    "sourceMap": true,
    "strict": true,
    "strictNullChecks": true,
    "target": "es6",
    "types": ["node"],
  },
}

Would you be willing to resolve this issue by submitting a Pull Request?


Indicate your interest in the resolution of this issue by adding the 👍 reaction. Comments such as "+1" will be removed.

ephys commented 1 year ago

You need to set your tsconfig moduleResolution option to node16 or nodenext: https://www.typescriptlang.org/docs/handbook/esm-node.html#packagejson-exports-imports-and-self-referencing

w0rldart commented 1 year ago

Thank you ephys for the reply. I will try it, but it doesn't make sense. Your own tsconfig has moduleResolution set just to node, like I do

image

If this turns out to be the issue, may I suggest that this is clearly reflected somewhere in the documentation?

ephys commented 1 year ago

Our own tsconfig should not be used as an example, it's overly complicated because we try to support multiple versions of TypeScript

I've converted this to a documentation issue

w0rldart commented 1 year ago

Our own tsconfig should not be used as an example, it's overly complicated because we try to support multiple versions of TypeScript

I've converted this to a documentation issue

It would be handy to have an example tsconfig.json that's suitable to use in a fresh V7 project

Lordfirespeed commented 11 months ago

This is pretty awful, I can't lie. NodeNext is practically unusable due to

The exports block is a lovely QoL feature when you're on NodeNext, but NodeNext being required to use v7 at all? :weary:

ephys commented 11 months ago

You can have path aliasing in your own project by configuring exports in your own package.json

The explanation for the different type of moduleResolutions is described here: https://www.typescriptlang.org/tsconfig#moduleResolution If that is not sufficient, I would recommend opening an issue on the TypeScript repo about it instead

You don't technically have to use Node16/NodeNext/Bundler (though I don't see why you wouldn't use the ts module resolution that accurately replicates how node resolves modules if you're using node). You can configure paths, or use resolvePackageJsonExports instead

Lordfirespeed commented 11 months ago

yeah, sorry. Was very frustrated last night. Turned out my path aliasing was working just fine but needed the .js extensions - the error was incredibly vague ('cannot resolve...')

WikiRik commented 11 months ago

We have opened https://github.com/sequelize/website/pull/583 to document this. Are we missing anything?

ephys commented 9 months ago

As mentioned in https://github.com/sequelize/sequelize/issues/16866, we also need to update the SSCCE repo's tsconfig

johneatmon commented 9 months ago

FWIW, you can set moduleResolution to "Bundler" and it also works. (TS notes that "This is the recommended setting in TypeScript 5.0+ for applications that use a bundler.")

I have Sequelize v7 with decorators working in a Next.js 14 project, and I'm basically using the default create-t3-app tsconfig.json. Posting this here in case anyone needs a similar resolution:

{
  "compilerOptions": {
    /* Base Options */
    "esModuleInterop": true,
    "skipLibCheck": true,
    "target": "ES2022",
    "allowJs": true,
    "resolveJsonModule": true,
    "moduleDetection": "force",
    "isolatedModules": true,
    /* Sequelize */
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "allowImportingTsExtensions": true,
    /* Strictness */
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "forceConsistentCasingInFileNames": true,
    "checkJs": true,
    /* Bundled projects */
    "lib": ["dom", "dom.iterable", "ES2022"],
    "noEmit": true,
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "jsx": "preserve",
    "plugins": [{ "name": "next" }],
    "incremental": true,
    /* Path aliases */
    "baseUrl": ".",
    "paths": {
      "@/*": ["./*"]
    },
    /* Needed for ts-node */
    "typeRoots": ["**/*.d.ts"]
  },
  "include": [
    ".eslintrc.cjs",
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx",
    "**/*.cjs",
    "**/*.js",
    ".next/types/**/*.ts"
  ],
  "exclude": ["node_modules"],
  "ts-node": {
    "esm": true
  }
}