ohm icon indicating copy to clipboard operation
ohm copied to clipboard

Uncaught TypeError: ohm.makeRecipe is not a function

Open etsai-stripe opened this issue 2 years ago • 2 comments

i have a generated ohm bundle file in my npm package i use the npm package in my react app but the client browser that loads the react app is throwing Uncaught TypeError: ohm.makeRecipe is not a function error in my package.json: "ohm-js": "^16.3.2",

is this version related? should i generate the bundle differently? i generated by the following command npx ohm generateBundles --withTypes src/grammar.ohm

etsai-stripe avatar May 19 '22 23:05 etsai-stripe

Hi, thanks for filing the issue and sorry for the slow reply...I'm currently on a 6-week camping trip with pretty limited internet access :-)

I don't think this is version-related. From what I can tell, the problem seems to be that makeRecipe was never included in the type definitions. Unfortunately I probably won't be able to fix this for a few weeks, but am happy to approve a pull request if you'd like to submit one! Note that you need to edit index.d.ts.template rather than directly editing index.d.ts.

pdubroy avatar Jun 06 '22 17:06 pdubroy

Facing a similar issue today -- not quite resolved but found I could work around in my case.

  • I was able to correctly use the compiled bundles (Language.ohm-bundle.d.ts and Language.ohm-bundle.js) directly in the context of Jest test execution and ts-node-based scripting.
  • The compiled bundles did not work in my setup when the same code was run in the browser (next.js react app) giving the error above (ohm.makeGrammar not a func)
  • The currently-working browser strategy with react (using next) I have is using raw-loader to parse the ohm grammar definition directly

jweissman avatar Jul 15 '22 00:07 jweissman

Taking another look at this as I clean up some bugs in preparation for the v17 release.

After re-reading this, I see that it has nothing to do with the type definitions. @etsai-stripe or @jweissman, can you give me some more details about how you are bundling?

pdubroy avatar Nov 06 '22 13:11 pdubroy

Never mind — I was able to reproduce this with webpack Ohm v16.3.4. It seems to be a problem related to ES modules and our use of a default export. For the record, I was able to fix it by modifying the .ohm-bundle.js file, replacing require('ohm-js') with require('ohm-js').default.

The good news is, it's already fixed on main and will be in the next release of Ohm (v17) and @ohm-js/cli. I'm also adding a test that ensures that grammars bundled with webpack work properly.

pdubroy avatar Nov 06 '22 13:11 pdubroy

Facing a similar issue today -- not quite resolved but found I could work around in my case.

  • I was able to correctly use the compiled bundles (Language.ohm-bundle.d.ts and Language.ohm-bundle.js) directly in the context of Jest test execution and ts-node-based scripting.
  • The compiled bundles did not work in my setup when the same code was run in the browser (next.js react app) giving the error above (ohm.makeGrammar not a func)
  • The currently-working browser strategy with react (using next) I have is using raw-loader to parse the ohm grammar definition directly

Can you post the relevant code from your working next.config?

ergodic1 avatar Nov 23 '22 21:11 ergodic1

For anyone else, a temporary workaround for nextjs as of 16.4.0 is to change the require in your cli generated ohm-bundles:

let ohm;
if (typeof window !== 'undefined') ohm = require('ohm-js').default;
else ohm = require('ohm-js');

ergodic1 avatar Nov 23 '22 21:11 ergodic1

Any eta for v17 then?

ex3ndr avatar Feb 26 '23 17:02 ex3ndr

@ex3ndr I plan to have it out by the end of the week.

pdubroy avatar Feb 27 '23 09:02 pdubroy

Any updates on this type error? Im having the same issue in a typescript tryout problem with the following settings:

dependencies: "ohm-js": "^17.1.0" "react": "^18.2.0",

devDependencies: "@ohm-js/cli": "^2.0.0"

GoncaloCamaz avatar May 03 '23 18:05 GoncaloCamaz

@GoncaloCamaz Hmmm, this should have been fixed with the v17 release. Can you share more details about how you are building/bundling your code?

pdubroy avatar May 04 '23 06:05 pdubroy

@GoncaloCamaz Hmmm, this should have been fixed with the v17 release. Can you share more details about how you are building/bundling your code?

Sure, Im buiding a tryout to experiment the lib. Have already the grammar defined and tested. After that I followed the approach in the docs regarding the usage with Typescript https://ohmjs.org/docs/typescript and it has generated the bundle files without any error. I have a text field where I insert the content to be parsed and then submit. However I cannot even see this since the error occurs while the component is mount.

However, after that i tried another approach and put the grammar in a config file, importing it and with this approach that is also on the docs I did not have the same issue so, for now, I will resume with this approach (importing the grammar from a config and import * as ohm from 'ohm-js'; .

GoncaloCamaz avatar May 04 '23 09:05 GoncaloCamaz

@GoncaloCamaz Thanks for the details. Can you also tell me exactly how you are running the final code? It sounds like you are using React. Are you bundling your code in some way? E.g., which bundler, exactly what command line, etc. Without the details like this it's difficult for me to reproduce the problem.

Can you please also clarify what you mean by "importing the grammar from a config"?

pdubroy avatar May 04 '23 18:05 pdubroy

In the current working version im doing the following imports: import * as ohm from 'ohm-js'; import { GRAMMAR, OHM_ACTIONS_DICT } from './config'; In this config file I have the grammar in a string constant and the actions for the interpreter.

Bellow I instantiate the grammar like so: const grammar = ohm.grammar(GRAMMAR); const interpreter = grammar.createSemantics().addOperation("parseContent", OHM_ACTIONS_DICT); And after I return the parse content result to a code editor to display the content in JSON format return interpreter(match).parseContent();

This way works fine!

Previously I was using the grammar object generated by the bundle, importing it like you have on the docs (https://ohmjs.org/docs/typescript): import grammar from '../src/grammar.ohm-bundle' To generate the bundle files, i followed the docs example and used the following command line: npx ohm generateBundles --withTypes src/grammar.ohm

The code sample where I instantiate the grammar object is displayed bellow and its the same for both versions:

const evaluateGrammar = useCallback((text: string): object | undefined=> {
	const match = grammar.match(text);
	if (match.succeeded()) {
		setStatus(EMatchStatus.Valid);
		setFailureMessage('');
		return interpreter(match).parseContent();
	} else {
		setStatus(EMatchStatus.Invalid);
		setFailureMessage(match.message);
		return undefined;
	}
}, [interpreter]);

For this tryout Im using React yes but the objective is to have this parser in a javascript utils program that acts as a middleware and that project is built in typescript. Since its built in typescript, I followed the docs example but I can work with the js example and then apply some interfaces to the results.

GoncaloCamaz avatar May 05 '23 08:05 GoncaloCamaz

Thanks for the additional details. But I still don't know how you're running the final code. What does your TypeScript configuration look like? Are you using a bundler like Webpack, Rollup, etc.? And if so, what are the bundler options? It's very difficult to debug this without knowing those things. If you could push your repo to GitHub I could take a look.

One possibility is that the rest of your code is using ES module, while the Ohm bundles are using require. Please note that there is a --esm option to generateBundles, which makes the bundles use import rather than require.

pdubroy avatar May 05 '23 18:05 pdubroy

@pdubroy thanks for your time and help! I was missing the --esm flag as I am working with ES Modules!

Thank you 👍

GoncaloCamaz avatar May 08 '23 18:05 GoncaloCamaz