Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamically precompile schemas: Error: compileSchemaValidators is not a function. #4012

Open
4 tasks done
magaton opened this issue Dec 27, 2023 · 9 comments
Open
4 tasks done
Labels

Comments

@magaton
Copy link

magaton commented Dec 27, 2023

Prerequisites

What theme are you using?

core

Version

5.x

Current Behavior

I am trying to precompile schemas using the provided code snippets from docs

Expected Behavior

No response

Steps To Reproduce

https://github.com/magaton/rjsf-issues

should help to reproduce.

Environment

- OS: mac osx
- Node: latest
- npm: latest

Anything else?

Could you please tell me what I am doing wrong?
I need to dynamically precompile schemas when the form is loading since the schema is super complex with lots of allOf and dependencies.

@magaton magaton added bug needs triage Initial label given, to be assigned correct labels and assigned labels Dec 27, 2023
@magaton magaton changed the title Dynamically precompile schemas compileSchemaValidators is not a function Dynamically precompile schemas: Errror: compileSchemaValidators is not a function. Dec 27, 2023
@magaton magaton changed the title Dynamically precompile schemas: Errror: compileSchemaValidators is not a function. Dynamically precompile schemas: Error: compileSchemaValidators is not a function. Dec 27, 2023
@nickgros
Copy link
Contributor

nickgros commented Jan 5, 2024

@zxbodya you added this in #3793, could you help @magaton ?

@zxbodya
Copy link
Contributor

zxbodya commented Jan 8, 2024

@magaton the reason you get compileSchemaValidators is not a function is that it is not exported in @rjsf/validator-ajv8. Instead it should be imported directly from @rjsf/validator-ajv8/dist/compileSchemaValidators.


However, there is a bigger issue about the code you have - compileSchemaValidatorsCode is not intended to be used in the browser (the whole point having precompiled schema is to avoid schema compilation on client-side, instead moving it to build step, or to server side for more advanced cases)

in docs you linked

the part:

const code = compileSchemaValidatorsCode(schema, options);

is supposed to be running server side, somewhere like api endpoint returning code text to be evaluated in the browser

@magaton
Copy link
Author

magaton commented Jan 9, 2024

Thanks @zxbodya!
As you can see, I am not a React developer, just trying to make my rjsf schema rendered correctly with as little as possible React dev.

If I do import as you suggest:

import { compileSchemaValidators } from '@rjsf/validator-ajv8/dist/compileSchemaValidators';

I am getting the following error:

Could not find a declaration file for module '@rjsf/validator-ajv8/dist/compileSchemaValidators'. '/Users/magaton/Projects/rjsf-issues/node_modules/@rjsf/validator-ajv8/dist/compileSchemaValidators.js' implicitly has an 'any' type.
  If the '@rjsf/validator-ajv8' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '@rjsf/validator-ajv8/dist/compileSchemaValidators';

If it is not too much to ask, would it be possible to provide a sample project / codesandbox that:

  • loads json schema from the file system in the Form component
  • imports compileSchemaValidators
  • does the magic explained in docs

Thanks in advance

@zxbodya
Copy link
Contributor

zxbodya commented Jan 10, 2024

Thanks @zxbodya! As you can see, I am not a React developer, just trying to make my rjsf schema rendered correctly with as little as possible React dev.

To clarify - why you are looking into precompiled schema validators, is it because you are trying to enforce the content security policy blocking unsafe-eval, and not allowing it to generate validators in the browser?

if not - you probably do not need to precompile the schama… you can just import @rjsf/validator-ajv8 and use it directly(compiling the validators in the browser).

Then, if you need to precompile it - do you need to do that dynamically?

If your schema is static and you do not need to load it from somewhere dynamically - you can precompile it once and then just include it as part of your bundle ("Schema precompilation" / "Using the precompiled validator" - sections in mentioned docs describe exactly this use-case)


Could not find a declaration file for module '@rjsf/validator-ajv8/dist/compileSchemaValidators'. '/Users/magaton/Projects/rjsf-issues/node_modules/@rjsf/validator-ajv8/dist/compileSchemaValidators.js' implicitly has an 'any' type.
If the '@rjsf/validator-ajv8' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '@rjsf/validator-ajv8/dist/compileSchemaValidators';

you can also use

import { compileSchemaValidators } from '@rjsf/validator-ajv8/lib/compileSchemaValidators';

(that will give correct types)

If it is not too much to ask, would it be possible to provide a sample project / codesandbox that:

  • loads json schema from the file system in the Form component
  • imports compileSchemaValidators
  • does the magic explained in docs

adopted the code in the docs into nextjs app - https://stackblitz.com/edit/stackblitz-starters-m5wjqy?file=app%2Fpage.tsx

@magaton
Copy link
Author

magaton commented Jan 10, 2024

Thanks very much @zxbodya .
I have applied your suggested changes and pushed to: repository
Now I am getting another error:
Module not found: Error: Can't resolve 'fs' in '/Users/magaton/Projects/rjsf-issues/node_modules/@rjsf/validator-ajv8/lib'
I understand this is the primary reason for exposing compileSchemaValidators in the first place?

What could be the solution?

To answer your WHY question :)

I want schema to be dynamically precompiled because:

  • the schema can be modified, so it needs to be fetched from the url. Loading from FS is just to simplify the example.
  • the performance of the generated form is quite poor (users experience long lags after each keystroke). My understanding after reading relevant issues here is that this happens because of many (nested) conditionals with allOf and if-then-else, that I simply have to use.

Thanks again!

@zxbodya
Copy link
Contributor

zxbodya commented Jan 10, 2024

Thanks very much @zxbodya . I have applied your suggested changes and pushed to: repository Now I am getting another error: Module not found: Error: Can't resolve 'fs' in '/Users/magaton/Projects/rjsf-issues/node_modules/@rjsf/validator-ajv8/lib' I understand this is the primary reason for exposing compileSchemaValidators in the first place?

What could be the solution?

the issue is that you are trying to run it in a browser environment, which is not expected and would not work.
compileSchemaValidators is supposed to be used only in nodejs environment.

In the example I shared, this part is running server side in nodejs, and it can not be moved to client-side code

To answer your WHY question :)

I want schema to be dynamically precompiled because:

  • the schema can be modified, so it needs to be fetched from the url. Loading from FS is just to simplify the example.
  • the performance of the generated form is quite poor (users experience long lags after each keystroke). My understanding after reading relevant issues here is that this happens because of many (nested) conditionals with allOf and if-then-else, that I simply have to use.

you do not have an issue with CSP? - if so, using @rjsf/validator-ajv8 without precompilation should be almost the same, and it also can be used with the schema loaded dynamically…

I would also not expect much performance difference there using the form, it might only take a bit longer to load - the validator should anyway compile the schema validators just once on load, and not each keystroke…

there is probably something else causing performance issues

@magaton
Copy link
Author

magaton commented Jan 10, 2024

Thanks, it is clear then i need to compile schema in browser, not on server side, like you showed.
But how to compile it in browser? I cannot find any working example.

Wrt, your doubt that precompiling schema upfront would help:
See this suggestion
on my comment.

I want to avoid compiling schemas on each key stroke, since it takes 3-4s.
I tried providing schema id explicitely, but that didnt help.

Please correct me if I misunderstood the whole thing.

@heath-freenome heath-freenome removed the needs triage Initial label given, to be assigned correct labels and assigned label Jan 12, 2024
@heath-freenome
Copy link
Member

heath-freenome commented Jan 12, 2024

@magaton are your schemas changing on the fly? If not, you can simply precompile the schema in your build and simply import it in your code. If it is changing on the fly, are kind of SOL unless you do SSR to compile it on the server

@magaton
Copy link
Author

magaton commented Jan 12, 2024

@heath-freenome , yes, my schemas can change on the fly, but I could live with compiling them on the server side. My understanding, based on this issue seems to be not correct was that schema precompilation is the key for the performance.

What I basically need is to eliminate 3-4s long lags after each key stroke.

Any advice is much appreciated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants