nuxt
nuxt copied to clipboard
Error when using parameter decorator in server middleware
Versions
- nuxt: v2.15.8
- node: v14.16.1
Reproduction
An error occurs when the parameter decorator is used in the server middleware.
I am using type-graphql
module in the project, and below is the code that causes the error.
Additional Details
I'm not sure, but I think it's a problem related to jiti.
This is my jiti version.
└─┬ [email protected]
├─┬ @nuxt/[email protected]
│ └── [email protected]
└─┬ @nuxt/[email protected]
└── [email protected] deduped
Steps to reproduce
import 'reflect-metadata'
import { Arg, Field, Int, Mutation, ObjectType, Query, Resolver } from 'type-graphql'
import { AutoIncrement, Column, DataType, IsInt, Length, Model, PrimaryKey, Table } from 'sequelize-typescript'
@Table
@ObjectType()
export class Department extends Model {
@IsInt
@Field(_type => Int)
@PrimaryKey
@AutoIncrement
@Column(DataType.INTEGER)
id: number
@Length({ min: 1, max: 20 })
@Field(_type => String)
@Column(DataType.STRING)
name: string
}
@Resolver(Department)
export class DepartmentResolver {
@Mutation(_returns => Department)
async add_department(
@Arg('name', _type => String) name: string // <--- Here
): Promise<Department> {
return await Department.create({ name })
}
}
What is Expected?
It should work.
What is actually happening?
Displayed error.
Decorating class property failed.
Please ensure that proposal-class-properties is enabled and runs after the decorators transform.
I have the same issue, is there any news on this?
Versions
Nuxt:2.15.8 Node: 14.15.1 Typescript:4.0.8
Reproduction
- Set up a local nuxt module
@/modules/test.ts
- Write simple code with usage of class decorators (example below)
- Add the module to nuxt.config.js
-
npm run dev
What is expected?
It should work.
What is actually happening?
The following error.
Error: Decorating class property failed. Please ensure that proposal-class-properties is enabled and runs after the decorators transform.
Here is the code to reproduce the issue in a simply local nuxt module using typescript
` import 'reflect-metadata' import { Module } from '@nuxt/types' import { Expose, plainToClass } from 'class-transformer'
class Category { @Expose() iAmWhitelisted: string }
const module: Module = function () { plainToClass(Category, { iAmWhitelisted: 'Foo', iAmNotWhitelisted: 'Foo', }) }
export default module
`
@fatheaddrummer I was able to solve this problem by referring to the code in the jiti repo. but it's pretty old code, so I'm not sure if it will work.
This is my nuxt.config.js code
import jiti from 'jiti'
import { transformSync } from '@babel/core'
export default {
...
createRequire: (jsFileName) => {
return jiti(jsFileName, {
// cache: false
debug: false,
legacy: true,
transform (opts) {
const _opts = {
babelrc: false,
configFile: false,
compact: false,
retainLines: typeof opts.retainLines === 'boolean' ? opts.retainLines : true,
filename: '',
cwd: '/',
...opts.babel,
plugins: [
[require('@babel/plugin-transform-modules-commonjs'), { allowTopLevelThis: true }],
[require('babel-plugin-dynamic-import-node'), { noInterop: true }],
[require('babel-plugin-transform-import-meta')],
[require('@babel/plugin-syntax-class-properties')]
]
}
const parameterDecorator = require('babel-plugin-parameter-decorator')
if (opts.ts) {
_opts.plugins.push([require('@babel/plugin-transform-typescript'), { allowDeclareFields: true, onlyRemoveTypeImports: true }])
// `unshift` because this plugin must come before `@babel/plugin-syntax-class-properties`
_opts.plugins.unshift([require('@babel/plugin-proposal-decorators'), { legacy: true }])
_opts.plugins.unshift(require('babel-plugin-transform-typescript-metadata'))
_opts.plugins.push(parameterDecorator)
}
if (opts.legacy) {
_opts.plugins.push(require('@babel/plugin-proposal-nullish-coalescing-operator'))
_opts.plugins.push(require('@babel/plugin-proposal-optional-chaining'))
}
// `babel-plugin-parameter-decorator` plugin must come after `@babel/plugin-proposal-class-properties`
const decoratorIndex = _opts.plugins.indexOf(parameterDecorator)
if (decoratorIndex !== -1) {
_opts.plugins.splice(decoratorIndex + 1, 0, [require('@babel/plugin-proposal-class-properties'), { loose: true }])
}
if (opts.babel && Array.isArray(opts.babel.plugins)) {
_opts.plugins?.push(...opts.babel.plugins)
}
try {
return {
code: transformSync(opts.source, _opts)?.code || ''
}
} catch (err) {
return {
error: err,
code: 'exports.__JITI_ERROR__ = ' + JSON.stringify({
filename: opts.filename,
line: err.loc?.line || 0,
column: err.loc?.column || 0,
code: err.code?.replace('BABEL_', '').replace('PARSE_ERROR', 'ParseError'),
message: err.message?.replace('/: ', '').replace(/\(.+\)\s*$/, '')
})
}
}
}
})
}
}
and I needed additional module installation once more.
npm i @babel/plugin-proposal-class-properties @babel/plugin-transform-typescript babel-plugin-parameter-decorator babel-plugin-transform-import-meta babel-plugin-transform-typescript-metadata --save-dev
If the problem is not solved, it may be a cache problem of jiti.
Please disable the cache by giving the cache: false
option.
Please forgive me for my poor English and I hope it was helpful.
Thanks for your contribution to Nuxt! This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you would like this issue to remain open:
- Verify that you can still reproduce the issue in the latest version of nuxt-edge
- Comment the steps to reproduce it
Issues that are labeled as pending
will not be automatically marked as stale.
I also have same problem. If anyone knows some workaround, I would like you to share it.
versions
- nuxt : 2.15.8
- node : 16.14.2
- yarn : 1.22.15
what I did
-
npx create-nuxt-app
- created the file
./api/index.ts
and./api/sample.ts
- add
serverMiddleware: ['~~/api/'],
to thenuxt.config.js
-
yarn dev
and access tohttp://localhost:3000/sample
errors shown
Decorating class property failed. Please ensure that proposal-class-properties is enabled and runs after the decorators transform.
files that were created
./api/index.ts
import express, { json, urlencoded } from 'express'
import { Sample } from './sample'
const app = express()
app.use(json())
app.use(urlencoded({ extended: true }))
app.get('/sample', (_request: express.Request, response: express.Response) => {
console.log(new Sample())
response.send({ message: 'OK' })
})
export default app
./api/sample.ts
const sampleDeco = (target: any, memberName: string) => {
let currentValue: string = target[memberName]
Object.defineProperty(target, memberName, {
set: (newValue: string) => {
currentValue = newValue
},
get: () => {
return currentValue
},
})
}
export class Sample {
@sampleDeco
aaa?: string
}
I'm facing a similar issue using json2typescript
in a server middleware. Seems likely it is related to jiti needing to use @babel/plugin-proposal-class-properties
instead of @babel/plugin-syntax-class-properties
.
https://github.com/unjs/jiti/issues/57
facing the similar issue with typeorm, anyone has workaround ?
@JasonGaoG With my particular issue I ended up having to make new models that were just for the server middleware. Then I could drop json2typescript
out of the files. It's not great since I have two sets of duplicate models in some spots but it worked.