mobx
mobx copied to clipboard
Documentation: Add installation.md note about Next.js
This adds a note for Next.js users, who (unintuitively) must configure babel (which is normally not needed at all) even if their project uses typescript. I think this is worth including because Next.js is relatively popular, and following the instructions as stated here simply doesn't work for unclear reasons. I spent the better part of an evening debugging this, only to eventually figure out that Next.js uses babel for compilation even if the project is set up with/written in typescript and doesn't have a babel config file yet.
Had I not had an evening free that I felt like spending on this, I probably would have given up entirely on MobX, as this was my first project to try it out and it seemed to just not work when used as directed (as all typescript-declared class fields without initial values were just mysteriously not tracked by makeAutoObservable)
See https://github.com/mobxjs/mobx/discussions/2831#discussioncomment-1937782 for related discussion / my journey in debugging this
The most staggering thing is that nowadays you shouldn't need to set this up at all, because these are defaults. But it depends on framework, it's version, it's compilation setup, babel version and presets version ... it's a mess.
Btw here: https://babeljs.io/docs/en/babel-plugin-transform-typescript#typescript-compiler-options they state:
--useDefineForClassFields
You can use the onlyRemoveTypeImports
option to replicate this behavior.
Dunno what other implications this has or if/how you can modify babel typescript plugin options in nextjs.
EDIT based on this: https://github.com/vercel/next.js/blob/canary/packages/next/build/babel/preset.ts I think it should be doable like:
"presets": [
["next/babel", { "preset-typescript": { "onlyRemoveTypeImports": true } }]
],
The most staggering thing is that nowadays you shouldn't need to set this up at all, because these are defaults. But it depends on framework, it's version, it's compilation setup, babel version and presets version ... it's a mess.
Btw here: https://babeljs.io/docs/en/babel-plugin-transform-typescript#typescript-compiler-options they state:
--useDefineForClassFields
You can use theonlyRemoveTypeImports
option to replicate this behavior. Dunno what other implications this has or if/how you can modify babel typescript plugin options in nextjs.EDIT based on this: https://github.com/vercel/next.js/blob/canary/packages/next/build/babel/preset.ts I think it should be doable like:
"presets": [ ["next/babel", { "preset-typescript": { "onlyRemoveTypeImports": true } }] ],
Just verifying that the above suggested .babelrc
does indeed fix the issue for Next.js with TypeScript.
Maybe it should be added to the updated documentation comment?
@jamieathans Does the issue exist in a fresh up-to-date Next.js setup?
@jamieathans Does the issue exist in a fresh up-to-date Next.js setup?
@kubk Just double checked this again using the following npm
versions (fresh Next.js setup):
{
"name": "nextjs-mobx",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"mobx": "6.6.0",
"mobx-react": "7.5.0",
"next": "12.1.6",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@types/node": "18.0.0",
"@types/react": "18.0.14",
"@types/react-dom": "18.0.5",
"eslint": "8.18.0",
"eslint-config-next": "12.1.6",
"typescript": "4.7.4"
}
}
What I have discovered is just the presence of a minimal .babelrc
as described here will fix the mobx issue:
{
"presets": ["next/babel"],
"plugins": []
}
Maybe this implies the issue is with SWC as I also see the following messages in the node dev terminal:
info - Disabled SWC as replacement for Babel because of custom Babel configuration ".babelrc" https://nextjs.org/docs/messages/swc-disabled
.
.
.
info - Using external babel configuration from /Users/jamie/projects/nextjs-mobx/.babelrc