feathers icon indicating copy to clipboard operation
feathers copied to clipboard

[@feathersjs/schema] `schema` function is not pure and crashes in ES Modules

Open FossPrime opened this issue 3 years ago • 5 comments

Steps to reproduce

  • Call schema twice with the same parameters.

Expected behavior

Don't crash.

Actual behavior

"schema with key or id "UserPatch" already exists"

System configuration

Module versions: dove pre Module Loader: esbuild

Reproduction:

use schema instead of safeSchema, wait for server restart, than modify a comment string. When the server is being restarted the bug will crash esbuild wasm as we are building in the same context and something global is conflicting... this might be unavoidable, so I propose wrapping schema with my fix when appropriate.

https://stackblitz.com/edit/bug-feathersjs-schema-2680?file=src%2Fschema%2Fusers.schema.ts,src%2Futils.ts

FossPrime avatar Jun 30 '22 18:06 FossPrime

I would see how AJV does this since the error is coming from there. We could work around it but I'm pretty sure someone needed to do hot module reloading with AJV before.

daffl avatar Jul 07 '22 17:07 daffl

I've ruled out upstream... I cannot reproduce the issue with [email protected] and [email protected]

https://stackblitz.com/edit/vitejs-vite-qdrpwy?file=BugReproduction.ts

With up to date @feathersjs/schema dependencies, I can no longer reproduce the issue at all!

https://stackblitz.com/edit/bug-feathersjs-schema-2680-vfz5ho?file=src%2Fschema%2Fusers.schema.ts,src%2FsafeSchema.ts,client.ts

FossPrime avatar Jul 20 '22 18:07 FossPrime

https://stackblitz.com/edit/feathers-vite-chat-ys59tp?file=src%2Fschema.ts,src%2Fschema%2Fusers.schema.ts,src%2Fschema%2Fmessages.schema.ts,client.ts

For some reason copying schema to your src makes the intellisense server not crash... https://stackblitz.com/edit/feathers-vite-chat-ys59tp?file=src%2Fschema%2Fusers.schema.ts

FossPrime avatar Jul 20 '22 22:07 FossPrime

The issue only manifests when loading a module from node_modules, if the module is anywhere else in the project, DEFAULT_AJV will be discarded, cleaning up any polluting modules. See PR.

FossPrime avatar Jul 21 '22 09:07 FossPrime

Other situations I can think of where this is a problem:

  • Running two feathers instances in the same context and both of them have a User schema.
  • Running tests on Schemas, you have to be careful to not name a schema the same as another test if the context is shared.
  • dynamically creating schemas from a feathers client
  • Monorepos where all projects are expected to run in the same node context
  • Clients that connect to multiple feathers servers

Normally we'd use the Feathers App's context... But that would probably break intellisence as the types couldn't be computed at ES Module compile time. Types are already slow to compile because App.ts has no constructor, so typescript can't process types without attempting to execute everything; Rather than processing only top level stateless statements that you'd expect when calling import './src/app.ts'

FossPrime avatar Jul 22 '22 16:07 FossPrime

This should be fixed in the next prerelease via https://github.com/feathersjs/feathers/pull/2702. Thank you for the PR!

daffl avatar Aug 30 '22 12:08 daffl