react-jsonschema-form
react-jsonschema-form copied to clipboard
Dynamically precompile schemas: Error: compileSchemaValidators is not a function.
Prerequisites
- [X] I have searched the existing issues
- [X] I understand that providing a SSCCE example is tremendously useful to the maintainers.
- [X] I have read the documentation
- [X] Ideally, I'm providing a sample JSFiddle, Codesandbox.io or preferably a shared playground link demonstrating the issue.
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.
@zxbodya you added this in #3793, could you help @magaton ?
@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)
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
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
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
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
allOfandif-then-else, that I simply have to use.
Thanks again!
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
allOfandif-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
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.
@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
@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.