I'm getting the following error after upgrading to 0.8.0:
TypeError: Class constructor Model cannot be invoked without 'new'
at new UserModel (/path/to/project/src/server/graphql/models/User/userModel.js:29:103)
at Function.fromDatabaseJson (/path/to/project/node_modules/objection/lib/model/Model.js:443:19)
at Object.createModels (/path/to/project/node_modules/objection/lib/queryBuilder/QueryBuilder.js:826:41)
at Object.tryCatcher (/path/to/project/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/path/to/project/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/path/to/project/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/path/to/project/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/path/to/project/node_modules/bluebird/js/release/promise.js:693:18)
at Async._drainQueue (/path/to/project/node_modules/bluebird/js/release/async.js:133:16)
at Async._drainQueues (/path/to/project/node_modules/bluebird/js/release/async.js:143:10)
at Immediate.Async.drainQueues (/path/to/project/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:672:20)
at tryOnImmediate (timers.js:645:5)
at processImmediate [as _immediateCallback] (timers.js:617:5)
EDIT:
As of objection 1.5.0 this problem should no longer exist. But please, stop transpiling your backend to ES5 in the year 2019! That's idiotic! Target node 6 in your babel config instead. Node 6, that has everything objection needs, was released four years ago! Surely you are not using node versions < 6 are you? Transpiling to ES5 will, among other things, use regenerator to rewrite your async/await code into a switch/case state machine that adds quite a bit of overhead.
END EDIT
Yep, please read the change log. Legacy node versions (0.10, 0.12) are no longer supported. You also need to migrate from the legacy ES5 inheritance to class and extend keywords. This is because of the way classes are implemented in Ecmascript. You cannot invoke class constructors without new and therefore this doesn't work:
class Model {
}
function UserModel() {
// You cannot do this.
Model.apply(this, arguments);
}
And since objection Model is a native ES2015 class, you get that error. If you are using Babel you need to remove the babel-plugin-transform-es2015-classes plugin that does the conversion. You don't need it anyway with node >= 4.0.0.
Check out the ESNext example project as an example of how to setup babel.
Thanks. I did look at the changelog, maybe you should be more explicit about Babel.
I have shared code between backend and frontend, guess I'll have to do some refactoring before I can upgrade to 0.8.x.
You're right, I'll add a mention about Babel & friends to the change log. I'll also leave this open for other people to find.
You can also make it so that babel is using your node version by doing something like this:
{
"presets": [
["env", {
"targets": {
"node": "current"
}
}],
"stage-1"
],
"plugins": []
}
@juhaelee Awesome, didn't know about that! Do you happen to know which Babel versions support that?
@koskimas I believe you can use it as long as you're using Babel 6. You just need to use the env preset package instead of es2015
I think this can be closed now that most people have migrated to objection 0.7.
I'm using babel-register, and have node_modules ignored by babel with this flag:
ignore: /\/(build|node_modules)\/(?!objection)/,
presets: [...
this means babel compiles my code on the fly, except for things being imported from my build/node_modules folder.
However, it turns out that objection does not compile into something es6+ compatible, so writing something like class User extends Model caused this error to appear.
Changing the babel config to ignore node_modules EXCEPT for objection made everything work (meaning it DID compile the objection library for me, but not other modules)
ignore: /\/(build|node_modules)\/(?!objection)/,
presets: [...
As I learned from this comment (and the ones below)
My versions:
Node v 7.5, babel 6, objection 0.9
@jnelken I don't know if I misunderstood something, but you don't need to transpile objection! The problem is not objection code but the way babel emulates classes in ES5. What you need to do is to turn off the class emulation since node 7.5 fully supports native classes. You don't need that emulation. That's what the env preset does.
@koskimas Ok, so it seems the react-app plugin I use for server-side rendering my react app is causing this, most likely by simulating classes as you mentioned. If I turn it off, I experience no problem. However I'm going to need it on and the quickest workaround seems to be the one I mentioned above (by transpiling the library) :/
Hi, I'm trying to use objection.js in a next.js project but am also running into this problem with [email protected] and [email protected]. I'm running Node v9.6.0.
It probably has something to do with their babel preset next/babel but am not sure how to fix this.
Looks like this is the preset: https://github.com/zeit/next.js/blob/canary/server/build/babel/preset.js
I'm not that familiar with next, but I did have this issue when running my Objection code in the server for testing with nightwatch.
For me, I had to execute require('babel-core/register'); _after_ I'd required all of my Objection code. I ended up fixing it and not worrying much about how/why too deeply, but there's also a bunch of stuff I found back then in this search that has to do with when/how to configure babel/es2015 that may help you, too:
https://www.google.com/search?q=nightwatch+babel-core%2Fregister&oq=nightwatch+babel-core%2Fregister&aqs=chrome..69i57j0j69i65l3j0.4102j0j7&sourceid=chrome&ie=UTF-8
Ran into this too. Objection should export ES5 code (perhaps something like objection/es5), because most people are using a transpiler, and this forces the user to modify their babel config which may affect other things.
World should be ready for ES6 classes by now. We will not add support for ES5.
I am trying to use objection.js with Node in AWS Lambda (Node 8.10). I struggled for a few hours until I hit the jackpot. I tried several configuration recommendations and what finally did the trick was excluding the babel-plugin-transform-classes in the preset-env options. I share this for future reference, since it may help others searching for the same solution.
Cheers!
// webpack.config.js
...
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
target: { node: '8.10' }, // Node version on AWS Lambda
modules: false,
exclude: ['babel-plugin-transform-classes'],
},
],
],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-transform-runtime',
],
},
},
},
...
Just in case it helps anyone, I had a lot of trouble with @babel/preset-env and objection because my .browserslistrc was being read and included in its targets, meaning the transform-classes plugin was being used for my node 8.9.4 code when in fact no transpilation of classes was necessary.
There is an ignoreBrowserslistConfig option you can use to avoid this.
If using TypeScript compiler, set output to at least es2015 in tsconfig.json
{
"compilerOptions": {
"target": "es2015"
}
}
I'm facing the same issue with Next.js. We use a single .babelrc inside a mono git repository. The web (Next.js) and api (Objection) servers live under two different folders, they share the same configuration.
I agree with @vjpr, I think that it would be simpler to publish a ES5 code in the npm package. I'm gonna start looking for a solution now.
1 hour later, my solution:
babelrc.js
const node = [`${__dirname}/src/api`]
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
ie: 11,
edge: 14,
firefox: 45,
chrome: 49,
safari: 10,
node: '6.11',
},
},
],
],
overrides: [
{
test: filename => node.some(prefix => filename.startsWith(prefix)),
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current',
},
},
],
],
},
],
}
Having the same issue. Cannot for the life of me get it to work.
Webpack babel-loader on node 10.7.0;
EDIT: It was my .browserslistrc that caused the error as noted by @inversion above.
Adding ignoreBrowserslistConfig": true to my babel config for the server solved the issue.
{
test: /\.js?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
babelrc: false,
presets: [
[
"@babel/preset-env",
{
modules: false,
targets: {
node: "current"
}
}
],
[
"@babel/preset-stage-0",
{
decoratorsLegacy: true,
pipelineProposal: "minimal"
}
],
"@babel/preset-react"
],
plugins: [
...(!WEBPACK_ENV.PRODUCTION ? ["react-hot-loader/babel"] : []),
"react-loadable/babel",
[
"babel-plugin-styled-components",
{
ssr: true,
displayName: !WEBPACK_ENV.PRODUCTION
}
]
]
}
}
}
@koskimas After all the reports, don't you think its worth transpiling it? I don't think the world is ready just yet. Most people run their code through babel, and its tricky to ignore one file from transpilation. It also entails having to ignore all the files that touch objection. Objection is the only lib in my stack that I need this complicated workaround for right now.
@vjpr Don't know your environment, but @inversion had a fix that worked for me, the error was unrelated to objection.
@vjpr No I don't think we should transpile objection. You should open issues in whatever project is preventing you from using libraries that use the class keyword.
I've tried babel transpilation for about a year but mainly do server-side dev and was pretty unpleased with the results.. until the ECMAScript guys can solve their (several year) battle of .js/.mjs, I'm sticking with common JS and "vanilla" node.
At any rate, classes are supported in most modern browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
And have been supported in Node since 6.4.0: https://node.green/#ES2015-functions-class
So perhaps I'm missing something here - but the majority of your babel issues seem to stem from mis-configurations.
Yeah this is difficult. My JS environment is pretty crazy because I'm using Razzle for server-side rendering of a React app, and I use react-native-web to share code with iOS/Android with the same codebase.
Because I'm using Razzle, I don't have full access to my full webpack+babel config. Even if I could edit my config, it would feel hacky to carve out an exception for objection.
Long story short, I found it easier to fork and compile objection to ES5+CommonJS, so that I don't hit this error. If anybody else wants to use my compiled version, you can add the following to your package.json:
"objection": "https://github.com/ericvicenti/objection.js",
@ericvicenti I ended up doing something similar, thanks for the idea
"objection": "https://github.com/thenanyu/objection.js"
compiled using @babel/preset-env with default settings, as it seems to be the fashionable approach. I'm using NextJs and trying to convince webpack to do the right thing in that env was a huge timesink.
I am trying to use objection.js with Node in AWS Lambda (Node 8.10). I struggled for a few hours until I hit the jackpot. I tried several configuration recommendations and what finally did the trick was excluding the
babel-plugin-transform-classesin thepreset-envoptions. I share this for future reference, since it may help others searching for the same solution.Cheers!
// webpack.config.js ... { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: [ [ '@babel/preset-env', { target: { node: '8.10' }, // Node version on AWS Lambda modules: false, exclude: ['babel-plugin-transform-classes'], }, ], ], plugins: [ '@babel/plugin-proposal-class-properties', '@babel/plugin-proposal-object-rest-spread', '@babel/plugin-transform-runtime', ], }, }, }, ...
This definitely helped me...
This is so painful. I don't know any other library that is using untranspiled ES6 classes that you inherit from.
Using babel overrides is really frustrating, and every new environment has to deal with it. E.g. Ava test babel config, Wallaby test babel config, webpack config, and project babel config. There are so many issues open about this and
👍
On Fri, 18 Jan 2019 at 17:47, Sami Koskimäki notifications@github.com
wrote:
@vjpr https://github.com/vjpr Please use some other library then.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/Vincit/objection.js/issues/388#issuecomment-455611821,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AARLRanODl0RXag6yy6Uqh6ExX_t_ST8ks5vEfqEgaJpZM4Nj8wd
.
@vjpr if babel is giving you so much problems, why are you using it? Even node 6 LTS is going out of maintenance in April (if I remember correctly), so I don't see why babel targetting es5 is so necessary... 🤔
Other thing you could do is to provide your own transpiled objection version available.
@vjpr Could you try out this commit in your package.json and import objection/babel instead of objection. I'm trying to support babel ES5 transpilation without actually transpiling objection.
@vjpr This commit removes the need to require('objection/babel'). The normal import { something } from 'objection' should now work.
@ericvicenti @thenanyu Could you also try pointing your package.json to this commit to see if it works with your setups without adding any special cases for objection?
also @Malouda :arrow_up:
@vjpr This commit removes the need to require('objection/babel'). The normal import { something } from 'objection' should now work.
@koskimas Cool! Seems to work. Can we get an npm published version?
@vjpr I can release an RC version right now, but I want to run some additional tests before releasing 1.5.0 (I've rewritten the insertGraph/upsertGraph code and want to make sure I didn't break anything).
You can install the RC version using npm install objection@next
Oh crap, some tests are broken because of this and I also need to wrap other classes. I'll probably release the next RC during the next week.
1.5.0-rc.5 is now released with the fix.
And now the official 1.5.0 is released. No need for @next tag anymore.
Most helpful comment
You can also make it so that babel is using your node version by doing something like this: